///////////////////////////////////////////////////////////////////////////////
// Projekt: O'n'X
// Autor: Lord Darkstorm
// Data utworzenia: 09.08.2013
// Opis: Deklaracja klasy NetMenuDialog
///////////////////////////////////////////////////////////////////////////////

#include "netmenudialog.h"
#include "ui_netmenudialog.h"

// Konstruktor ////////////////////////////////////////////////////////////////

NetMenuDialog::NetMenuDialog(QWidget *parent) :
  QDialog(parent, Qt::WindowTitleHint),
  ui(new Ui::NetMenuDialog)
{
  ui -> setupUi(this) ;

  canceled = false ;
  server = new QTcpServer(this) ;
  socket = new QTcpSocket(this) ;

  connect(ui -> createServerButton, SIGNAL(clicked() ), this, SLOT(createServer() ) ) ;
  connect(ui -> connectToServerButton, SIGNAL(clicked() ), this, SLOT(connectToServer() ) ) ;
  connect(ui -> returnButton, SIGNAL(clicked() ), this, SLOT(cancel() ) ) ;
  connect(server, SIGNAL(newConnection() ), this, SLOT(connected() ) ) ;
  connect(socket, SIGNAL(readyRead() ), this, SLOT(setStartingPlayer() ) )  ;
}

// Destruktor /////////////////////////////////////////////////////////////////

NetMenuDialog::~NetMenuDialog()
{
  delete ui ;
}

// createServer ///////////////////////////////////////////////////////////////
// Metoda tworzy serwer, który oczekuje na połączenie z zewnątrz.

void NetMenuDialog::createServer()
{
  // Jeśli z jakiegoś powodu nie uda się utworzyć serwera,
  // otrzymujemy stosowną informację o zajściu.

  if (!server -> listen(QHostAddress::Any, 12000) )
  {
    QMessageBox::critical(this, "Błąd", "Nie udało się utworzyć serwera.") ;
    return ;
  }
  else
  {
    // W przeciwnym razie czekamy na połączenie.

    ui -> createServerButton -> setDisabled(true) ;
    ui -> connectToServerButton -> setDisabled(true) ;
    ui -> ipAddressField -> setDisabled(true) ;

    ui -> infoField -> insertPlainText("Tworzenie serwera gry: [OK]\nOczekiwanie na połączenie...") ;
  }
}

// connectToServer /////////////////////////////////////////////////////////////
// Metoda łączy się ze serwerem w celu utworzenia gry.

void NetMenuDialog::connectToServer()
{
  // Pobieramy adres IP od usera.

  QString ipAddress = ui -> ipAddressField -> text() ;

  // Małe zabezpieczenie przed łączeniem się z pustym IP ;).

  if (ipAddress.isEmpty() )
  {
    QMessageBox::warning(this, "Adres IP", "Wprowadź IP serwera, z którym chcesz się połączyć.") ;
    return ;
  }

  // Łączymy się ze serwerem.

  socket -> connectToHost(ui -> ipAddressField -> text(), 12000) ;

  // Jeśli nie będzie odpowiedzi ze strony serwera w przeciągu 5 sekund,
  // metoda wyświetla odpowiedni komunikat i kończy działanie.

  if (!socket -> waitForConnected(5000) )
  {
    QMessageBox::critical(this, "Błąd", "Wystąpił błąd przy próbie połączenia. Sprawdź IP serwera i spróbuj ponownie.") ;
    return ;
  }
  else
  {
    // Inaczaj ruchamy się z tym.

    ui -> createServerButton -> setDisabled(true) ;
    ui -> connectToServerButton -> setDisabled(true) ;
    ui -> returnButton -> setDisabled(true) ;
    ui -> ipAddressField -> setDisabled(true) ;

    ui -> infoField -> insertPlainText("Udało się połączyć ze serwerem.\nOczekiwanie na reakcję ze strony serwera...") ;
  }
}

// connected //////////////////////////////////////////////////////////////////////
// Metoda wywoływana w momencie otrzymania połączenia.

void NetMenuDialog::connected()
{
  // Przekazanie gniazdu nadeszłego połączenia

  socket = server -> nextPendingConnection() ;

  ui -> infoField -> insertPlainText("Nawiązano połączenie z: " + socket -> peerAddress().toString() ) ;

  // Losujemy zaczynającego.
  // Wysyłamy klientowi informację o tym, kto zaczyna.
  // Zapamiętujemy deskryptor gniazda.
  // Zamykamy dialog.

  whoStarts = qrand() % 2 ;

  if (whoStarts)
  {
    ui -> infoField -> insertPlainText("Rozpoczynasz grę.") ;
    socket -> write("true") ;
  }
  else
  {
    ui -> infoField -> insertPlainText("Przeciwnik rozpoczyna grę.") ;
    socket -> write("false") ;
  }

  socketID = socket -> socketDescriptor() ;

  this -> close() ;
}

// cancel //////////////////////////////////////////////////////////////////////////

void NetMenuDialog::cancel()
{
  if (server -> isListening() )
  {
    server -> close() ;
  }

  canceled = true ;

  this -> close() ;
}

// setStartingPlayer //////////////////////////////////////////////////////////////////
// Odczytujemy informację od serwera, kto zaczyna i zapamiętujemy deskryptor gniazda.

void NetMenuDialog::setStartingPlayer()
{
  QByteArray array = socket -> readAll() ;

  if (array == "true")
  {
    whoStarts = false ;
    ui -> infoField -> insertPlainText("Przeciwnik rozpoczyna grę.") ;
  }
  else
  {
    whoStarts = true ;
    ui -> infoField -> insertPlainText("Rozpoczynasz grę.") ;
  }

  socketID = socket -> socketDescriptor() ;

  this -> close() ;
}
